package com.aw.baselib.util.update

import android.content.Context
import android.util.Log
import com.aw.baselib.base.AwBaseApplication
import com.aw.baselib.util.AwDataUtil
import com.aw.baselib.util.AwFileUtil
import com.aw.baselib.util.AwLog
import okhttp3.Call
import okhttp3.Callback
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.util.concurrent.TimeUnit

/**
 * Created by hzw
 */
class AwFileDownloadUtil private constructor() {
    private val okHttpClient: OkHttpClient

    init {
        okHttpClient = OkHttpClient()
    }

    fun downApk(context: Context, url: String, listener: OnDownloadListener) {
        if (AwBaseApplication.downCalls?.containsKey(url) == true) {
            listener.onDownloadIngRejectRepeat()
            return
        }
        val file = getFile(context, url)
        if (file.exists()) {
            listener.onDownloading(100)
            success(url, listener, file.absolutePath)
            return
        }
        get(url, object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                fail(context, url, listener)
            }

            @Throws(IOException::class)
            override fun onResponse(call: Call, response: Response) {
                var `is`: InputStream? = null //输入流
                var fos: FileOutputStream? = null //输出流
                try {
                    `is` = response.body()!!.byteStream() //获取输入流
                    val total = response.body()!!.contentLength() //获取文件大小
                    //view.setMax(total);//为progressDialog设置大小
                    if (`is` != null) {
                        Log.d("SettingPresenter", "onResponse: 不为空")
                        fos = FileOutputStream(file)
                        val buf = ByteArray(2048)
                        var ch = -1
                        var process = 0
                        while (`is`.read(buf).also { ch = it } != -1) {
                            fos.write(buf, 0, ch)
                            process += ch
                            val progress = (process * 1.0f / total * 100).toInt()
                            listener.onDownloading(progress)
                        }
                    }
                    fos!!.flush()
                    // 下载完成
                    if (fos != null) {
                        fos.close()
                    }
                    success(url, listener, file.absolutePath)
                } catch (e: Exception) {
                    fail(context, url, listener)
                } finally {
                    try {
                        `is`?.close()
                    } catch (e: IOException) {
                    }
                    try {
                        fos?.close()
                    } catch (e: IOException) {
                    }
                }
            }
        })
    }

    operator fun get(address: String, callback: Callback?) {
        val client = OkHttpClient()
        client.newBuilder().connectTimeout(1, TimeUnit.MINUTES).readTimeout(1, TimeUnit.MINUTES)
            .writeTimeout(1, TimeUnit.MINUTES)
        val builder = FormBody.Builder()
        val body = builder.build()
        val request = Request.Builder()
            .url(address)
            .build()
        val call = client.newCall(request)
        AwBaseApplication.downCalls?.set(address, call) //把这个添加到call里,方便取消
        call.enqueue(callback)
    }

    interface OnDownloadListener {
        /**
         * 下载成功
         */
        fun onDownloadSuccess(path: String?)

        /**
         * @param progress 下载进度
         */
        fun onDownloading(progress: Int)

        /**
         * 下载失败
         */
        fun onDownloadFailed(path: String?)

        /**
         * 正在下载, 拒绝重复
         */
        fun onDownloadIngRejectRepeat()
    }

    fun cancel(context: Context, url: String) {
        AwFileUtil.deleteFile(getFile(context, url))
        if (AwBaseApplication.downCalls == null) {
            return
        }
        val call = AwBaseApplication.downCalls!![url]
        if (call != null) {
            call.cancel() //取消
            AwBaseApplication.downCalls!!.remove(url)
            AwLog.d("下载取消了")
        }
    }

    fun success(url: String?, listener: OnDownloadListener, path: String?) {
        listener.onDownloadSuccess(path)
        //        DaoCacheFileUtil.getInstance().updateBean(url);
        AwBaseApplication.downCalls?.remove(url)
    }

    fun fail(context: Context, url: String, listener: OnDownloadListener) {
        listener.onDownloadFailed(url)
        cancel(context, url)
    }

    fun getFile(context: Context, url: String): File {
        val name = getUrlLastName(url)
        AwLog.d("AwFileDownloadUtil getFile name: $name")
        val file = File(context.getExternalFilesDir(""), name)
        if (!file.parentFile.exists()) {
            file.parentFile.mkdirs()
        }
        //storage/emulated/0/Android/data/com.sirun.terminal/files/TerminalManager_10011_test.apk
        AwLog.d("AwFileDownloadUtil getFile filepath: " + file.absolutePath)
        return file
    }

    companion object {
        private var downloadUtil: AwFileDownloadUtil? = null
        @JvmStatic
        fun get(): AwFileDownloadUtil? {
            if (downloadUtil == null) {
                downloadUtil = AwFileDownloadUtil()
            }
            return downloadUtil
        }

        fun getUrlLastName(param: String): String {
            return if (AwDataUtil.isEmpty(param)) {
                ""
            } else param.substring(param.lastIndexOf("/") + 1)
        }
    }
}